#pragma once
#include "audio_output.h"
#include "audio_output_fft.h"
#include "audio_mixer.h"
#include "audio_sound.h"
#include "audio_sound_3d.h"
#include "audio_input.h"
#include "audio_input_wave.h"
#include "audio_input_ogg.h"
#include "audio_filter.h"

#include "audio_output_openal.h"

using namespace krryn::math;

namespace krryn{
namespace audio{
	/// Simplest possible dependency injector, it's here to centeralize
	/// the coupling and to promote decoupling of classes.
	class di{
	public:
		output::ptr create_output(){
			return create_fft().as<output>();
		}

		output_fft::ptr create_fft(){
			output_fft::ptr l_Temp(new output_fft(create_device()));
			l_Temp->add_filter(new filter_low_pass(200000));
			return l_Temp;
		}

		output::ptr create_device(){
			return output::create();
		}

		mixer::ptr create_mixer(){
			return mixer::ptr(new mixer(create_device()));
		}

		listener::ptr create_listener(){
			static listener::ptr l_Listener(new listener());
			return l_Listener;
		}

		input::ptr create_input(const std::string &a_Filename){
			return input::ptr(new input_wave(a_Filename));
		}

		sound::ptr create_sound(const std::string &a_Filename){
			return sound::ptr(new sound(create_input(a_Filename)));
		}

		sound_3d::ptr create_sound_3d(
			const std::string &a_Filename, 
			const vector3f &a_Position){

			sound_3d::ptr l_Sound(new sound_3d(
				create_sound(a_Filename), 
				create_listener(),
				a_Position
			));

			return l_Sound;
		}
	};
}
}
